package com.itheima.d8_interface2;


import com.itheima.d5_abstract2.Animal;
import com.itheima.d5_abstract2.Cat;




/**
 * 认识接口
 * Java提供了一个关键字interface，用这个关键字我们可以定义出一个特殊的结构：接口。
 * 注意：接口不能创建对象；接口是用来被类实现（implements）的，实现接口的类称为实现类。
 * 一个类可以实现多个接口（接口可以理解成干爹），实现类实现多个接口，必须重写完全部接口的全部抽象方法，否则实现类需要定义成抽象类。
 */

/**
 * 1、接口是什么？
 * 使用interface关键字定义的一种结构， JDK 8之前，接口中只能定义成员变量和成员方法。
 * 2、接口怎么使用？需要注意什么？
 * 接口 是被类 实现的。
 *
 *
 * 实现类实现多个接口，必须重写完全部接口的全部抽象方法，否则实现类需要定义成抽象类。
 * 3、接口的好处是啥？
 * 弥补了类单继承的不足，类可以同时实现多个接口。
 * 让程序可以面向接口编程，这样既不用关心实现的细节，也可以灵活方便的切换各种实现。
 */

/**
 * 1、使用接口有啥好处，第一个好处是什么？
 * 可以解决类单继承的问题，通过接口，我们可以让一个类有一个亲爹的同时，还可以找多个干爹去扩展自己的功能。
 * 2、为什么我们要通过接口，也就是去找干爹，来扩展自己的功能呢？
 * 因为通过接口去找干爹，别人通过你implements的接口，就可以显性的知道你是谁，从而也就可以放心的把你当作谁来用了。
 * 3、使用接口的第二个好处是什么？
 * 一个类我们说可以实现多个接口，同样，一个接口也可以被多个类实现的。这样做的好处是我们的程序就可以面向接口编程了，这样我们程序员就可以很方便的灵活切换各种业务实现了。
 */

/**
 * - **接口是用来被类实现（implements）的,实现也就是继承，我们称之为实现类，实现类也就是子类。**
 * - **一个类是可以实现多个接口的（接口可以理解成干爹），类实现接口必须重写所有接口的全部抽象方法，否则这个类也必须是抽象类**
 */

public class Test {
    public static void main(String[] args) {
        // 目标：搞清楚使用接口的好处。接口不能实例化创建对象
        //但是这里调用的是实现类-A的构造器所创建的对象。A类实现singer接口，所以singer接口相当于干爹
        Singer s = new A();  //想唱歌的时候，用singer类型的变量接对象，A类对象就表现为Singer类型
        s.sing();   //所以调用方法的时候，也得是调用子类父类都有的方法

        //A类实现driver接口，所以driver接口相当于干爹
        Driver d = new A();  //想开车的时候，用driver类型的变量接对象，A类对象就表现为Driver类型
        d.drive();  //所以调用方法的时候，也得是调用子类父类都有的方法

        //假设A对象不好使，面向接口编程就非常好用，直接换成B对象，其他代码也不用改，方便切换各种实现
        Driver d1 = new B();
        d1.drive();

        //A类继承于student，所以student相当于父类亲爹
        Student s1 = new A();   //用student类型的变量接a类对象
        /*
        *  s1.sing();  报错不行,因为是子类独有的方法
            使用instanceof判断当前对象的真实类型：对象 instanceof 当前对象的真实类型 。
            * */
        if(s1 instanceof A){
            //((A) s1).sing();
            A s2 = (A) s1;
            System.out.println("现在是student强制转换为A类型之后的：");
            s2.sing();
        }


        Animal a = new Cat();
        a.cry();
    }
}

class B implements Driver {
    @Override
    public void drive() {

    }
}

/**
 * 假设有一个Studnet学生类，还有一个Driver司机的接口，还有一个Singer歌手的接口。
 * 现在要写一个A类，想让他既是学生，偶然也是司机能够开车，偶尔也是歌手能够唱歌
 */
class A extends Student implements Driver,Singer{

    @Override
    public void drive() {
        System.out.println("我是A类里面重写过的driver方法");
    }

    @Override
    public void sing() {
        System.out.println("我是A类里面重写过的sing方法");
    }
}

class Student{

}

interface Driver{
    void drive();
}

interface Singer{
    void sing();
}